package com.cloud.yun;

/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.util.HashMap;
import java.util.Map;

/**
 * Goal which touches a timestamp file.
 *
 * @goal touch
 * @phase process-sources
 */
@Mojo(name = "MybatisPlusGenerator")
public class MybatisPlusGeneratorMojo extends AbstractMojo {

    /**
     * 生成文件所在项目路径
     */
    @Parameter(property = "MybatisPlusGenerator.filePath", required = true)
    private String filePath;

    /**
     * 模块名称
     */
    @Parameter(property = "MybatisPlusGenerator.moduleName", required = true)
    private String moduleName;

    /**
     * 要生成的表名,用","分割
     */
    @Parameter(property = "MybatisPlusGenerator.tables", required = true)
    private String tables;
    /**
     * table前缀
     */
    private static final String PREFIX = "";
    /**
     * 数据库配置四要素
     */
    private static final String driverName = "com.mysql.cj.jdbc.Driver";
    private static final String username = "root";
    private static final String password = "91MySQL_171";

    @Override
    public void execute() throws MojoExecutionException {

        String[] tableList;
        if (StringUtils.isNotEmpty(tables)) {
            tableList = tables.split(",");
        } else {
            throw new MojoExecutionException("生成表名未填写");
        }

        // 代码生成器
        AutoGenerator gen = new AutoGenerator();
        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://192.168.9.171:3306/cloud_" + moduleName +
                "?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai");
        dsc.setDriverName(driverName);
        dsc.setUsername(username);
        dsc.setPassword(password);
        dsc.setTypeConvert(new MySqlTypeConvert() {
            @Override
            public IColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
                System.out.println("转换类型：" + fieldType);
                //tinyint转换成Boolean
                if (fieldType.toLowerCase().contains("tinyint")) {
                    return DbColumnType.BOOLEAN;
                }
                //将数据库中datetime转换成date
                if (fieldType.toLowerCase().contains("timestamp")) {
                    return DbColumnType.DATE;
                }
                return (DbColumnType) super.processTypeConvert(globalConfig, fieldType);
            }
        });
        gen.setDataSource(dsc);

        // 全局配置
        gen.setGlobalConfig(new GlobalConfig()
                // 输出目录
                .setOutputDir(filePath)
                // 是否覆盖文件
                .setFileOverride(true)
                // 开启 activeRecord 模式
                .setActiveRecord(true)
                // XML 二级缓存
                .setEnableCache(false)
                // XML ResultMap
                .setBaseResultMap(true)
                // XML columnList
                .setBaseColumnList(true)
                // 生成后打开文件夹
                .setOpen(true)
                .setSwagger2(false)
                .setAuthor("Administrator")
                .setIdType(IdType.AUTO)
                .setDateType(DateType.ONLY_DATE)
                // 自定义文件命名，注意 %s 会自动填充表实体属性！
                .setMapperName("%sMapper").setXmlName("%sMapper").setServiceName("%sService")
                .setServiceImplName("%sServiceImpl").setControllerName("%sController"));

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        // .setCapitalMode(true)// 全局大写命名
        // .setDbColumnUnderline(true)//全局下划线命名
        // 此处可以修改为您的表前缀
        strategy.setTablePrefix(PREFIX)
                // 表名生成策略
                .setNaming(NamingStrategy.underline_to_camel)
                // 需要生成的表
                .setInclude(tableList)
                .setRestControllerStyle(true)
                .setVersionFieldName("version")
                // 自定义实体父类
                .setSuperEntityClass("com.cloud.common.base.entity.BaseEntity")
                .setSuperMapperClass("com.cloud.common.base.mapper.BaseMapper")
                .setSuperServiceClass("com.cloud.common.base.service.IBaseService")
                .setSuperServiceImplClass("com.cloud.common.base.service.impl.BaseServiceImpl")
                // 自定义实体，公共字段
                .setSuperEntityColumns("id", "is_deleted", "created_time", "created_by", "updated_time", "updated_by", "version")
                // 【实体】是否为lombok模型（默认 false）<a href="https://projectlombok.org/">document</a>
                .setEntityLombokModel(false)
                // Boolean类型字段是否移除is前缀处理
                .setEntityBooleanColumnRemoveIsPrefix(true)
                //实体是否生成 serialVersionUID
                .setEntitySerialVersionUID(true)
                //驼峰转连字符
                .setControllerMappingHyphenStyle(true);
        strategy.setSuperMapperClass("com.cloud.common.base.mapper.BaseMapper");
        strategy.setSuperServiceClass("com.cloud.common.base.service.IBaseService");
        strategy.setSuperServiceImplClass("com.cloud.common.base.service.impl.BaseServiceImpl");
        strategy.setSuperControllerClass("com.cloud.common.base.controller.BaseController");
        gen.setStrategy(strategy);

        // 包名策略配置
        PackageConfig packageConfig = new PackageConfig();
        //模块名称，单独生成模块时使用！！！！！！！！！！！
        // packageConfig.setModuleName("User")
        // 自定义包路径
        packageConfig.setParent("com.cloud." + moduleName);
        // 这里是控制器包名，默认 web
        packageConfig.setController("controller");
        packageConfig.setEntity("entity");
        packageConfig.setMapper("dao");
        packageConfig.setService("service");
        packageConfig.setServiceImpl("service.impl");
        packageConfig.setXml("mapper");

        gen.setPackageInfo(packageConfig);

        // 注入自定义配置，可以在 VM 中使用 cfg.abc 设置的值
        InjectionConfig injectionConfig = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<>(4);
                map.put("abc", "abc");
                this.setMap(map);
            }
        };
        gen.setCfg(injectionConfig);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        // 自定义模板配置，模板可以参考源码 /mybatis-plus/src/main/resources/template 使用 copy
        // 至您项目 src/main/resources/template 目录下，模板名称也可自定义如下配置：
        templateConfig.setController("/templates/controller.java.vm");
        // 关闭默认 xml 生成，调整生成 至 根目录
        templateConfig.setXml("/templates/mapper.xml.vm");
        templateConfig.setEntity("/templates/entity.java.vm");
        templateConfig.setMapper("/templates/mapper.java.vm");
        templateConfig.setService("/templates/service.java.vm");
        templateConfig.setServiceImpl("/templates/serviceImpl.java.vm");
        // 模板配置
        gen.setTemplate(templateConfig);
        // 执行生成
        gen.execute();
        System.out.println("代码生成成功");
    }
}
